package edu.ccut.saturn.component.loader.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;
import org.dom4j.Text;

import edu.ccut.saturn.component.ISaturnDataSqlInfo;
import edu.ccut.saturn.component.ISaturnDataSqlItemInfo;
import edu.ccut.saturn.component.impl.sql.SaturnDataSqlInfo;

public class SqlLoader {

	public static final String NODE_KEY_SQL = "sql";

	public static final String NODE_KEY_ID = "id";

	public static final String NODE_KEY_DESCRIPTION = "description";

	@SuppressWarnings("unchecked")
	public static Map<String, ISaturnDataSqlInfo> getSqlMap(Element root)
			throws Exception {

		Map<String, ISaturnDataSqlInfo> sqlInfoMap = new HashMap<String, ISaturnDataSqlInfo>();
		List<Element> sqlElements = root.elements(NODE_KEY_SQL);

		for (Element sqlElement : sqlElements) {
			String id = sqlElement.attributeValue(NODE_KEY_ID);
			String description = sqlElement.elementText(NODE_KEY_DESCRIPTION);
			// List subElements = formatElements(sqlElement.content());
			List subElements = sqlElement.content();

			List<ISaturnDataSqlItemInfo> sqlItemInfos = getSqlItemInfos(subElements);
			SaturnDataSqlInfo saturnDataSqlInfo = new SaturnDataSqlInfo(id,
					description);

			saturnDataSqlInfo.setSqlItemInfos(sqlItemInfos);
			sqlInfoMap.put(id, saturnDataSqlInfo);
		}
		return sqlInfoMap;
	}

	@SuppressWarnings("unchecked")
	public static List formatElements(List content) {
		List elements = new ArrayList();
		StringBuffer textBuffer = new StringBuffer();

		for (Object element : content) {

			if (element instanceof Text) {

				if (isCompleteTextElement(element, textBuffer)) {
					textBuffer = new StringBuffer();
					elements.add(element);

				} else {
					textBuffer.append(((Text) element).getText());

				}

			} else if (element instanceof Element) {
				elements.add(element);
			}
		}
		return elements;
	}

	private static boolean isCompleteTextElement(Object element,
			StringBuffer buffer) {

		if (buffer != null && buffer.length() == 0) {
			String text = ((Text) element).getText();

			if (text.indexOf("${") == -1 && text.indexOf("}") == -1) {
				return true;

			} else if (text.lastIndexOf("}") > text.lastIndexOf("${")) {
				return true;

			} else if (text.lastIndexOf("${") > text.lastIndexOf("}")) {
				// buffer.append(text);
				return false;
			}

		} else {
			String text = ((Text) element).getText();
			buffer.append(text);

			if (text.lastIndexOf("}") > text.lastIndexOf("${")) {
				((Text) element).setText(buffer.toString());
				// buffer = new StringBuffer();
				return true;
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	private static List<ISaturnDataSqlItemInfo> getSqlItemInfos(List subElements)
			throws Exception {

		List elements = formatElements(subElements);
		List<ISaturnDataSqlItemInfo> itemInfos = new ArrayList<ISaturnDataSqlItemInfo>();

		for (Object element : elements) {

			ISqlItemInfoLoader sqlItemInfoLoader = null;

			if (element instanceof Text) {
				sqlItemInfoLoader = SqlItemLoaderFactory.getInstance()
						.createSqlItemInfoLoader("text");

			} else if (element instanceof Element) {
				sqlItemInfoLoader = SqlItemLoaderFactory.getInstance()
						.createSqlItemInfoLoader(((Element) element).getName());

			}

			if (sqlItemInfoLoader != null) {
				ISaturnDataSqlItemInfo sqlItemInfo = sqlItemInfoLoader
						.loadSqlItemInfo(element);

				if (sqlItemInfo != null) {
					itemInfos.add(sqlItemInfo);
				}
			}
		}
		return itemInfos;
	}
}
